-- David Siegel, Jonathan Coveney, HW #8

module Routine (Routine (..), RoutineF,
                RoutineName, RoutineDescription, RoutineUsage,
                lookupRoutine, lookupRoutineF
                ) where

import Term

------------------------------------------------------------
-- Public types
------------------------------------------------------------

-- Routine fields
type RoutineName        = String
type RoutineDescription = String
type RoutineUsage       = String

-- A routine function -- performs the routine on the program
-- state; first parameter is user input, second is the current
-- KnowledgeBase.
type RoutineF = String -> KnowledgeBase -> IO ()

-- A Routine describes a command that a user interactively
-- performs in the main event loop.
--
--   * Simple routines are routines that do not require special usage
--     instuctions ("help").
--
--   * Complex routines supply extra usage intructions (e.g. prove provides
--     "prove SENTENCE").
data Routine = Simple  RoutineName RoutineDescription RoutineF
             | Complex RoutineName RoutineDescription RoutineUsage RoutineF

------------------------------------------------------------
-- Public method declarations
------------------------------------------------------------

-- Given a routine name, looks for a routine by that name
-- in routines.
lookupRoutine :: RoutineName -> [Routine] -> Maybe Routine

-- Given a routine name, looks for a routine by that name
-- in routines. Returns that routine's point of entry.
lookupRoutineF :: RoutineName -> [Routine] -> Maybe RoutineF

------------------------------------------------------------
-- Public method definitions
------------------------------------------------------------

instance Show Routine where
    show (Simple  c d _)   = concat [c, " - ", d, ":\n", "  > ", c]
    show (Complex c d u _) = concat [c, " - ", d, ":\n", "  > ", u]

lookupRoutine s routines =
    aux routines
    where aux []     = Nothing
          aux (r:rs) = case r of
              (Simple  command _ _)   -> 
                  if command == s then Just r else aux rs
              (Complex command _ _ _) ->
                  if command == s then Just r else aux rs

lookupRoutineF s routines = case lookupRoutine s routines of
                                Just (Simple  _ _ f)   -> Just f
                                Just (Complex _ _ _ f) -> Just f
                                _                      -> Nothing
